package gamagora.game.entity
{
	import gamagora.game.world.OSWorld;
	
	import org.flixel.FlxSprite;
	
	public class OSEntity extends FlxSprite
	{
		public static const NOTHING:uint = 0;
		public static const PLAYER:uint = 1;
		public static const GROUND:uint = 2;
		public static const ANIMATION:uint = 3;
		public static const BRIDGE:uint = 4;
		public static const FIRE_GROUND:uint = 5;
		public static const MOVING_BOX:uint = 6;
		
		protected var _type:uint;
		protected var _world:OSWorld;
		protected var _startX:Number;
		protected var _startY:Number;
		protected var _scrolling:Boolean;
		protected var _inWorld:Boolean;
		protected var _hide:Boolean; //Cache le conteneur mais pas les enfants
		protected var _scroll:Number;
		protected var _oldX:Number;
		
		//Conteneur
		protected var _entities:Vector.<OSEntity>;
		protected var _nbEntities:uint;
		
		public function OSEntity(type:uint, X:Number=0, Y:Number=0, SimpleGraphic:Class=null, scrolling:Boolean = true)
		{
			super(X, Y, SimpleGraphic);
			_type = type;
			_startX = X;
			_startY = Y;
			_scrolling = scrolling;
			_inWorld = false;
			_hide = false;
			_scroll = 0;
			_oldX = 0;
			_entities = new Vector.<OSEntity>();
			_nbEntities = 0;
		}
		
		public function add(entity:OSEntity):void
		{
			_entities.push(entity);
			_nbEntities++;
		}
		
		public function remove(entity:OSEntity):void
		{
			_entities.splice(_entities.indexOf(entity), 1);
			_nbEntities--;
		}
		
		public function addToWorld():void
		{
			_inWorld = true;
			for(var i:uint=0;i<_nbEntities;i++)
			{
				if(!_entities[i].inWorld)
				{
					addEntityToWorld(_entities[i]);
				}
			}
		}
		
		public function removeFromWorld():void
		{
			_inWorld = false;
			for(var i:uint=0;i<_nbEntities;i++)
			{
				if(_entities[i].inWorld)
				{
					removeEntityFromWorld(_entities[i]);
				}
			}
		}
		
		public function setStartX(decalX:Number):void
		{
			x += decalX;
			_startX += decalX;
			for(var i:uint=0;i<_nbEntities;i++)
			{
				_entities[i].setStartX(decalX);
			}
		}
		
		public function setScroll(scroll:Number):void
		{
			_scroll = scroll;
			for(var i:uint=0;i<_nbEntities;i++)
			{
				_entities[i].setScroll(scroll);
			}
		}
		
		public function resetEntity():void
		{
			super.reset(_startX, _startY);
			for(var i:uint=0;i<_nbEntities;i++)
			{
				_entities[i].resetEntity();
			}
		}
		
		//Utils
		
		protected function addEntityToWorld(entity:OSEntity):void
		{
			entity.addToWorld();
			_world.add(entity);
		}
		
		protected function removeEntityFromWorld(entity:OSEntity):void
		{
			_world.remove(entity, true);
			entity.removeFromWorld();
		}
		
		//Override from flixel
		
		public override function update():void
		{
			super.update();
			for(var i:uint=0;i<_nbEntities;i++)
			{
				_entities[i].update();
			}
		}
		
		public override function draw():void
		{
			if(visible)
			{
				if(!_hide)
				{
					if(_scrolling)
					{
						_oldX = x;
						x += _scroll;
						super.draw();
						x = _oldX;
					}
					else
					{
						super.draw();
					}
				}
				for(var i:uint=0;i<_nbEntities;i++)
				{
					_entities[i].draw();
				}
			}
		}
		
		public override function kill():void
		{
			super.kill();
			for(var i:uint=0;i<_nbEntities;i++)
			{
				_entities[i].kill();
			}
		}
		
		public override function destroy():void
		{
			super.destroy();
			for(var i:uint=0;i<_nbEntities;i++)
			{
				_entities[i].destroy();
			}
		}
		
		//Getters Setters
		
		public function set world(value:OSWorld):void
		{
			_world = value;
			for(var i:uint=0;i<_nbEntities;i++)
			{
				_entities[i].world = value;
			}
		}
		
		public function get scrolling():Boolean
		{
			return _scrolling;
		}
		
		public function set scrolling(value:Boolean):void
		{
			_scrolling = value;
		}

		public function get inWorld():Boolean
		{
			return _inWorld;
		}

		public function get type():uint
		{
			return _type;
		}

		public function get scroll():Number
		{
			return _scroll;
		}

		public function get hide():Boolean
		{
			return _hide;
		}

		public function set hide(value:Boolean):void
		{
			_hide = value;
		}

	}
}
